<%#
 Copyright 2013-2025 the original author or authors from the JHipster project.

 This file is part of the JHipster project, see https://www.jhipster.tech/
 for more information.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      https://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-%>
<%_ if (clientTestFrameworkVitest) { _%>
import { afterEach, beforeEach, describe, expect, it, vitest } from 'vitest';
<%_ } _%>
import { DOCUMENT } from '@angular/common';
import { provideHttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Title } from '@angular/platform-browser';
import { Router, TitleStrategy } from '@angular/router';

<%_ if (enableTranslation) { _%>
import { InterpolatableTranslationObject, LangChangeEvent, TranslateModule, TranslateService } from '@ngx-translate/core';
<%_ } _%>
import { Subject, of } from 'rxjs';

import { AppPageTitleStrategy } from 'app/app-page-title-strategy';
import { AccountService } from 'app/core/auth/account.service';
<%_ if (enableI18nRTL) { _%>
import FindLanguageFromKeyPipe from 'app/shared/language/find-language-from-key.pipe';
<%_ } _%>

import Main from './main';

describe('Main', () => {
  let comp: Main;
  let fixture: ComponentFixture<Main>;
  let titleService: Title;
<%_ if (enableTranslation) { _%>
  let translateService: TranslateService;
  let langChangeSubject: Subject<LangChangeEvent>;
  <%_ if (enableI18nRTL) { _%>
  let findLanguageFromKeyPipe: FindLanguageFromKeyPipe;
  <%_ } _%>
<%_ } _%>
  const routerState: any = { snapshot: { root: { data: {} } } };
  let router: Router;
  let document: Document;

  beforeEach(() => {
    TestBed.configureTestingModule({
<%_ if (enableTranslation) { _%>
      imports: [TranslateModule.forRoot()],
<%_ } _%>
      providers: [
        provideHttpClient(),
        Title,
<%_ if (enableI18nRTL) { _%>
        FindLanguageFromKeyPipe,
<%_ } _%>
        {
          provide: AccountService,
          useValue: {
            identity: <%= clientTestFramework %>.fn(() => of(null)),
          },
        },
        { provide: TitleStrategy, useClass: AppPageTitleStrategy },
      ],
    });
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(Main);
    comp = fixture.componentInstance;
    titleService = TestBed.inject(Title);
<%_ if (enableTranslation) { _%>
    translateService = TestBed.inject(TranslateService);
  <%_ if (enableI18nRTL) { _%>
    findLanguageFromKeyPipe = TestBed.inject(FindLanguageFromKeyPipe);
  <%_ } _%>
<%_ } _%>
    router = TestBed.inject(Router);
    document = TestBed.inject(DOCUMENT);
    <%_ if (enableTranslation) { _%>
    langChangeSubject = new Subject<LangChangeEvent>();
    Object.defineProperty(translateService, 'onLangChange', {
      value: langChangeSubject,
      writable: true,
    });
    <%_ } _%>
  });

  describe('page title', () => {
    const defaultPageTitle = '<% if (enableTranslation) { %>global.title<% } else { %><%= humanizedBaseName %><% } %>';
    const parentRoutePageTitle = 'parentTitle';
    const childRoutePageTitle = 'childTitle';
<%_ if (enableTranslation) { _%>
    const langChangeEvent: LangChangeEvent = { lang: '<%= nativeLanguage %>', translations: {} as InterpolatableTranslationObject };
<%_ } _%>

    beforeEach(() => {
      routerState.snapshot.root = { data: {} };
<%_ if (enableTranslation) { _%>
      <%= clientTestFramework %>.spyOn(translateService, 'get').mockImplementation((key: string | string[]) => of(`${key as string} translated`));
      <%= clientTestFramework %>.spyOn(translateService, 'getCurrentLang').mockReturnValue('<%= nativeLanguage %>');
<%_ } _%>
      <%= clientTestFramework %>.spyOn(titleService, 'setTitle');
      comp.ngOnInit();
    });

    describe('navigation end', () => {
      it('should set page title to default title if pageTitle is missing on routes', async () => {
        // WHEN
        await router.navigateByUrl('');

        // THEN
        expect(document.title).toBe(defaultPageTitle<% if (enableTranslation) { %> + ' translated'<% } %>);
      });

      it('should set page title to root route pageTitle if there is no child routes', async () => {
        // GIVEN
        router.resetConfig([{ path: '', title: parentRoutePageTitle, component: Blank }]);

        // WHEN
        await router.navigateByUrl('');

        // THEN
        expect(document.title).toBe(parentRoutePageTitle<% if (enableTranslation) { %> + ' translated'<% } %>);
      });

      it('should set page title to child route pageTitle if child routes exist and pageTitle is set for child route', async () => {
        // GIVEN
        router.resetConfig([
          {
            path: 'home',
            title: parentRoutePageTitle,
            children: [{ path: '', title: childRoutePageTitle, component: Blank }],
          },
        ]);

        // WHEN
        await router.navigateByUrl('home');

        // THEN
        expect(document.title).toBe(childRoutePageTitle<% if (enableTranslation) { %> + ' translated'<% } %>);
      });

      it('should set page title to parent route pageTitle if child routes exists but pageTitle is not set for child route data', async () => {
        // GIVEN
        router.resetConfig([
          {
            path: 'home',
            title: parentRoutePageTitle,
            children: [{ path: '', component: Blank }],
          },
        ]);

        // WHEN
        await router.navigateByUrl('home');

        // THEN
        expect(document.title).toBe(parentRoutePageTitle<% if (enableTranslation) { %> + ' translated'<% } %>);
      });
    });
<%_ if (enableTranslation) { _%>

    describe('language change', () => {
      it('should set page title to default title if pageTitle is missing on routes', () => {
        // WHEN
        langChangeSubject.next(langChangeEvent);

        // THEN
        expect(document.title).toBe(`${defaultPageTitle} translated`);
      });

      it('should set page title to root route pageTitle if there is no child routes', async () => {
        // GIVEN
        routerState.snapshot.root.data = { pageTitle: parentRoutePageTitle };
        router.resetConfig([{ path: '', title: parentRoutePageTitle, component: Blank }]);

        // WHEN
        await router.navigateByUrl('');

        // THEN
        expect(document.title).toBe(`${parentRoutePageTitle} translated`);

        // GIVEN
        document.title = 'other title';

        // WHEN
        langChangeSubject.next(langChangeEvent);

        // THEN
        expect(document.title).toBe(`${parentRoutePageTitle} translated`);
      });

      it('should set page title to child route pageTitle if child routes exist and pageTitle is set for child route', async () => {
        // GIVEN
        router.resetConfig([
          {
            path: 'home',
            title: parentRoutePageTitle,
            children: [{ path: '', title: childRoutePageTitle, component: Blank }],
          },
        ]);

        // WHEN
        await router.navigateByUrl('home');

        // THEN
        expect(document.title).toBe(`${childRoutePageTitle} translated`);

        // GIVEN
        document.title = 'other title';

        // WHEN
        langChangeSubject.next(langChangeEvent);

        // THEN
        expect(document.title).toBe(`${childRoutePageTitle} translated`);
      });

      it('should set page title to parent route pageTitle if child routes exists but pageTitle is not set for child route data', async () => {
        // GIVEN
        router.resetConfig([
          {
            path: 'home',
            title: parentRoutePageTitle,
            children: [{ path: '', component: Blank }],
          },
        ]);

        // WHEN
        await router.navigateByUrl('home');

        // THEN
        expect(document.title).toBe(`${parentRoutePageTitle} translated`);

        // GIVEN
        document.title = 'other title';

        // WHEN
        langChangeSubject.next(langChangeEvent);

        // THEN
        expect(document.title).toBe(`${parentRoutePageTitle} translated`);
      });
    });
<%_ } _%>
  });
<%_ if (enableTranslation) { _%>

  describe('page language attribute', () => {
    it('should change page language attribute on language change', () => {
      // GIVEN
      comp.ngOnInit();

      // WHEN
  <%_ if (enableI18nRTL) { _%>
      findLanguageFromKeyPipe.isRTL = <%= clientTestFramework %>.fn(() => false);
  <%_ } _%>
      langChangeSubject.next({ lang: 'lang1', translations: {} as InterpolatableTranslationObject });

      // THEN
      expect(document.querySelector('html')?.getAttribute('lang')).toEqual('lang1');
  <%_ if (enableI18nRTL) { _%>
      expect(document.querySelector('html')?.getAttribute('dir')).toEqual('ltr');
  <%_ } _%>

      // WHEN
  <%_ if (enableI18nRTL) { _%>
      findLanguageFromKeyPipe.isRTL = <%= clientTestFramework %>.fn(() => true);
  <%_ } _%>
      langChangeSubject.next({ lang: 'lang2', translations: {} as InterpolatableTranslationObject });

      // THEN
      expect(document.querySelector('html')?.getAttribute('lang')).toEqual('lang2');
  <%_ if (enableI18nRTL) { _%>
      expect(document.querySelector('html')?.getAttribute('dir')).toEqual('rtl');
  <%_ } _%>
    });
  });
<%_ } _%>
});

@Component({
  template: '',
})
export class Blank {}
